package com.yitong.equipment.base

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.blankj.utilcode.util.LogUtils
import com.yitong.equipment.entity.base.BaseRes
import com.yitong.equipment.entity.other.ResState
import com.yitong.equipment.network.RetrofitManager
import com.yitong.equipment.network.SubscriberCallBack
import io.reactivex.*
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.*
import java.util.concurrent.TimeUnit

open class BaseViewModel(application: Application) : AndroidViewModel(application), LifecycleObserver {
    private var mCompositeDisposable: CompositeDisposable? = null
    protected var apiService = RetrofitManager.apiService
    val resState by lazy { MutableLiveData<ResState>() }

    protected fun <T : BaseRes<*>> Observable<T>.execute(subscriberCallBack: SubscriberCallBack<T>) {
        throttleFirst(500, TimeUnit.MILLISECONDS)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(subscriberCallBack)
    }

    protected fun Completable.subscribeDbWithoutCallBack(onSuccess: () -> Unit, onFailed: (e: Throwable) -> Unit) {
            subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object :CompletableObserver{
                override fun onSubscribe(d: Disposable) {
                    addDisposable(d)
                }

                override fun onComplete() {
                    onSuccess()
                }

                override fun onError(e: Throwable) {
                    onFailed(e)
                }

            })
    }


    protected fun <T> Single<T>.subscribeDbWithCallBack(onSuccess: (data: T) -> Unit, onFailed: (e: Throwable) -> Unit) {
            subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : SingleObserver<T> {
                override fun onSuccess(t: T) {
                    onSuccess(t)
                }

                override fun onSubscribe(d: Disposable) {
                    addDisposable(d)
                }

                override fun onError(e: Throwable) {
                    onFailed(e)
                }
            })
    }


    /**
     * kotlin 网络请求
     */
    protected fun <T : BaseRes<*>>  getNetData(action: T, onSuccess: (data: T) -> Unit, onFailed: (e: Throwable) -> Unit, onComplete: () -> Unit) {
        viewModelScope.launch {
            val result = try {
                Result.success(action)
            } catch (e: Exception) {
                Result.failure(e)
            }

            result.onFailure {
                onComplete()
                onFailed(it)
            }
            result.onSuccess {
                onComplete()
                onSuccess(it)
            }
        }
    }


    protected fun addDisposable(disposable: Disposable?) {
        if (mCompositeDisposable == null) {
            mCompositeDisposable = CompositeDisposable()
        }
        mCompositeDisposable!!.add(disposable!!)
    }


    fun launch(isMain:Boolean  = false, block: suspend CoroutineScope.() -> Unit): Job {
        return viewModelScope.launch {
            withContext(if (isMain) Dispatchers.Main else Dispatchers.IO) {
                block.invoke(this)
            }
        }
    }

    public override fun onCleared() {
        super.onCleared()
        if (mCompositeDisposable != null && !mCompositeDisposable!!.isDisposed) {
            mCompositeDisposable!!.clear()
        }
    }


}


